<template>
  <BasicModal
    v-bind="$attrs"
    :title="getTitle"
    :width="1050"
    :centered="false"
    @register="registerModal"
    @ok="handleSubmit"
    @cancel="handleCancel"
  >
    <div class="data-resource-modal">
      <!-- Section 1: Basic Information -->
      <div class="section">
        <h3 class="section-title">{{ t('tb.dataResource.modal.basicInfo') }}</h3>
        <BasicForm @register="registerForm">
          <template #data_source_info="{ model, field }">
            <div class="flex items-center gap-2">
              <Input
                v-model:value="model[field]"
                disabled
                :placeholder="t('tb.dataResource.modal.placeholders.dataSourceInfo')"
                style="flex: 1"
              />
              <a-button type="link" size="small" :disabled="!formValues.data_source_id" @click="handleTestConnection">
                测试连接
              </a-button>
            </div>
          </template>
        </BasicForm>

        <!-- Table Selection Area (only for database type) -->
        <div v-if="formValues.resource_type === 'database'" class="table-selection-area mt-4">
          <div class="flex items-center justify-between mb-2">
            <label class="font-medium">{{ t('tb.dataResource.modal.tableSelection') }}</label>
            <a-button size="small" type="link" @click="handleFetchTables">
              <Icon icon="ant-design:reload-outlined" />
              {{ t('tb.dataResource.modal.refreshTables') }}
            </a-button>
          </div>
          <Spin :spinning="loadingTables">
            <div v-if="availableTables.length > 0" class="border rounded p-3 max-h-48 overflow-y-auto">
              <CheckboxGroup
                v-model:value="selectedTables"
                class="table-checkbox-group"
                @change="handleCheckboxGroupChange"
              >
                <Checkbox v-for="table in availableTables" :key="table" :value="table" class="table-checkbox-item">
                  {{ table }}
                </Checkbox>
              </CheckboxGroup>
            </div>
            <Empty v-else :description="t('tb.dataResource.modal.noTablesAvailable')" />
          </Spin>
        </div>
      </div>

      <!-- Section 2: Field Mapping & Masking Configuration -->
      <div v-if="selectedTables.length > 0" class="section mt-6">
        <h3 class="section-title">{{ t('tb.dataResource.modal.fieldMapping') }}</h3>
        <Tabs v-model:activeKey="activeTableTab" type="card">
          <TabPane v-for="tableName in selectedTables" :key="tableName" :tab="tableName">
            <Spin :spinning="loadingFields[tableName]">
              <Table
                :columns="fieldColumns"
                :data-source="tableFieldConfigs[tableName] || []"
                :pagination="false"
                size="small"
                :scroll="{ y: 400 }"
                row-key="original_field"
              >
                <template #bodyCell="{ column, record, index }">
                  <template v-if="column.dataIndex === 'field_mapping'">
                    <Input
                      v-model:value="record.field_mapping"
                      :placeholder="t('tb.dataResource.modal.placeholders.fieldMapping')"
                      size="small"
                    />
                  </template>
                  <template v-else-if="column.dataIndex === 'masking_rule'">
                    <Select
                      v-model:value="record.masking_rule"
                      :options="maskingOptions"
                      size="small"
                      style="width: 120px"
                    />
                  </template>
                </template>
              </Table>
            </Spin>
          </TabPane>
        </Tabs>
      </div>
    </div>
  </BasicModal>
</template>

<script lang="ts" setup>
  import { ref, computed, reactive, watch, nextTick } from 'vue';
  import { BasicModal, useModalInner } from '/@/components/Modal';
  import { BasicForm, FormSchema, useForm } from '/@/components/Form';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { Icon } from '/@/components/Icon';
  import { Checkbox, CheckboxGroup, Tabs, TabPane, Table, Spin, Empty, Select, Input } from 'ant-design-vue';
  import {
    createDataResource,
    updateDataResource,
    type ServiceDataResource,
    type ServiceDataSource,
    type CreateDataResourcePayload,
    type UpdateDataResourcePayload,
  } from '/@/api/service/dataSource';
  import { defHttp } from '/@/utils/http/axios';

  type ResourceType = 'database' | 'api' | 'file';

  interface FieldConfig {
    original_field: string;
    field_mapping: string;
    masking_rule: string;
  }

  const emit = defineEmits(['success', 'register']);

  const { t } = useI18n();
  const { showMessage } = useMessage();

  const isUpdate = ref(false);
  const recordData = ref<ServiceDataResource | null>(null);
  const availableSources = ref<ServiceDataSource[]>([]);
  const deviceId = ref<string>('');
  const formValues = reactive<{
    resource_type: ResourceType;
    data_source_id: string;
    data_source_info: string;
    resource_name: string;
    description: string;
  }>({
    resource_type: 'database',
    data_source_id: '',
    data_source_info: '',
    resource_name: '',
    description: '',
  });

  // Table selection related
  const availableTables = ref<string[]>([]);
  const selectedTables = ref<string[]>([]);
  const loadingTables = ref(false);

  // Field mapping related
  const activeTableTab = ref('');
  const tableFieldConfigs = ref<Record<string, FieldConfig[]>>({});
  const loadingFields = reactive<Record<string, boolean>>({});


  const getTitle = computed(() =>
    isUpdate.value ? t('tb.dataResource.modal.editTitle') : t('tb.dataResource.modal.createTitle'),
  );

  const maskingOptions = [
    { label: t('tb.dataResource.modal.masking.none'), value: 'none' },
    { label: t('tb.dataResource.modal.masking.hash'), value: 'hash' },
    { label: t('tb.dataResource.modal.masking.middle'), value: 'middle' },
    { label: t('tb.dataResource.modal.masking.prefix'), value: 'prefix' },
    { label: t('tb.dataResource.modal.masking.suffix'), value: 'suffix' },
  ];

  const fieldColumns = [
    {
      title: t('tb.dataResource.modal.columns.originalField'),
      dataIndex: 'original_field',
      width: 200,
    },
    {
      title: t('tb.dataResource.modal.columns.fieldMapping'),
      dataIndex: 'field_mapping',
      width: 200,
    },
    {
      title: t('tb.dataResource.modal.columns.maskingRule'),
      dataIndex: 'masking_rule',
      width: 150,
    },
  ];

  const formSchema: FormSchema[] = [
    {
      field: 'resource_type',
      label: t('tb.dataResource.modal.resourceType'),
      component: 'Select',
      required: true,
      defaultValue: 'database',
      componentProps: {
        options: [
          { label: 'API', value: 'api' },
          { label: t('tb.dataResource.types.database'), value: 'database' },
          { label: t('tb.dataResource.types.file'), value: 'file' },
        ],
        onChange: (value: ResourceType) => {
          formValues.resource_type = value;

          // Clear data source selection
          clearDataSourceFields();
          setFieldsValue({
            resource_type: value,
            data_source_id: '',
            data_source_info: '',
          });
        },
      },
      colProps: { span: 12 },
    },
    {
      field: 'data_source_id',
      label: t('tb.dataResource.modal.dataSource'),
      component: 'Select',
      required: true,
      componentProps: ({ formModel }) => ({
        showSearch: true,
        allowClear: true,
        optionFilterProp: 'label',
        placeholder: t('tb.dataResource.form.placeholders.dataSource'),
        options: availableSources.value
          .filter((item) => item.type === formValues.resource_type)
          .map((item) => ({
            label: item.name,
            value: item.data_source_id,
          })),
        onChange: (value: string) => {
          if (!value) {
            clearDataSourceFields();
            setFieldsValue({
              resource_type: formValues.resource_type,
              data_source_id: '',
              data_source_info: '',
            });
            return;
          }

          const source = availableSources.value.find((s) => s.data_source_id === value);
          if (source) {
            formValues.data_source_id = source.data_source_id;
            formValues.data_source_info = formatDataSourceInfo(source);

            setFieldsValue({
              resource_type: formValues.resource_type,
              data_source_id: value,
              data_source_info: formValues.data_source_info,
            });

            // Reset selections
            selectedTables.value = [];
            tableFieldConfigs.value = {};

            // If database type, automatically load tables
            if (formValues.resource_type === 'database' && source.table) {
              const tables = Array.isArray(source.table) ? source.table : [source.table];
              availableTables.value = tables;
            } else {
              availableTables.value = [];
            }
          }
        },
      }),
      colProps: { span: 12 },
    },
    {
      field: 'data_source_info',
      label: t('tb.dataResource.modal.dataSourceInfo'),
      component: 'Input',
      componentProps: {
        disabled: true,
        placeholder: t('tb.dataResource.modal.placeholders.dataSourceInfo'),
      },
      slot: 'data_source_info',
    },
    {
      field: 'resource_name',
      label: t('tb.dataResource.form.resourceName'),
      component: 'Input',
      required: true,
      componentProps: {
        placeholder: t('tb.dataResource.form.placeholders.resourceName'),
      },
    },
    {
      field: 'description',
      label: t('tb.dataResource.modal.description'),
      component: 'InputTextArea',
      componentProps: {
        rows: 3,
        placeholder: t('tb.dataResource.form.placeholders.remark'),
      },
    },
  ];

  const [registerForm, { validate, setFieldsValue, resetFields, getFieldsValue }] = useForm({
    schemas: formSchema,
    labelWidth: 150,
    showActionButtonGroup: false,
    baseColProps: { span: 24 },
  });

  const [registerModal, { setModalProps, closeModal }] = useModalInner(
    async (data?: {
      isUpdate?: boolean;
      record?: ServiceDataResource;
      dataSources?: ServiceDataSource[];
      defaultType?: ResourceType;
      deviceId?: string;
    }) => {
      resetFields();
      setModalProps({ confirmLoading: false });

      isUpdate.value = !!data?.isUpdate;
      recordData.value = data?.record || null;

      // Use mock data if no real data sources provided
      if (!data?.dataSources || data.dataSources.length === 0) {
        availableSources.value = getMockDataSources();
      } else {
        availableSources.value = data.dataSources;
      }

      deviceId.value = data?.deviceId || 'mock-device-id';

      // Reset state
      selectedTables.value = [];
      availableTables.value = [];
      tableFieldConfigs.value = {};
      Object.keys(loadingFields).forEach((key) => delete loadingFields[key]);

      formValues.resource_type = (data?.defaultType as ResourceType) || 'database';
      formValues.data_source_id = '';
      formValues.data_source_info = '';
      formValues.resource_name = '';
      formValues.description = '';

      if (isUpdate.value && recordData.value) {
        const record = recordData.value;
        setFieldsValue({
          resource_type: record.type as ResourceType,
          data_source_id: record.data_source_id,
          resource_name: record.resource_name,
          description: record.remark,
        });
        formValues.resource_type = record.type as ResourceType;
        formValues.data_source_id = record.data_source_id;
        formValues.resource_name = record.resource_name;
        formValues.description = record.remark || '';

        // Set data source info
        const source = availableSources.value.find((s) => s.data_source_id === record.data_source_id);
        if (source) {
          formValues.data_source_info = formatDataSourceInfo(source);
          setFieldsValue({ data_source_info: formValues.data_source_info });
        }
      } else {
        setFieldsValue({
          resource_type: formValues.resource_type,
        });
      }
    },
  );

  // Mock data sources for testing
  function getMockDataSources(): ServiceDataSource[] {
    return [
      {
        '.name': 'mysql_prod_db',
        '.index': 1,
        data_source_id: 'ds_mysql_001',
        name: 'MySQL生产数据库',
        type: 'database',
        db_type: 'mysql',
        host: '192.168.1.100',
        port: '3306',
        user: 'admin',
        password: '******',
        database: 'production_db',
        table: ['users', 'orders', 'products', 'customers', 'transactions'],
        remark: 'MySQL生产环境数据库',
        owner: '张三',
      },
      {
        '.name': 'postgres_analytics',
        '.index': 2,
        data_source_id: 'ds_pg_002',
        name: 'PostgreSQL分析库',
        type: 'database',
        db_type: 'postgresql',
        host: '192.168.1.101',
        port: '5432',
        user: 'postgres',
        password: '******',
        database: 'analytics_db',
        table: ['sales_data', 'user_behavior', 'reports', 'metrics'],
        remark: 'PostgreSQL分析数据库',
        owner: '李四',
      },
      {
        '.name': 'api_service',
        '.index': 3,
        data_source_id: 'ds_api_003',
        name: 'REST API服务',
        type: 'api',
        host: 'api.example.com',
        port: '443',
        remark: 'RESTful API数据源',
        owner: '王五',
      },
    ];
  }

  // Helper: Format data source info string
  function formatDataSourceInfo(source: ServiceDataSource): string {
    return `${source.type || ''} | ${source.host || ''}:${source.port || ''} | ${source.database || ''}`;
  }

  // Helper: Clear data source related fields
  function clearDataSourceFields() {
    formValues.data_source_id = '';
    formValues.data_source_info = '';
    selectedTables.value = [];
    availableTables.value = [];
    tableFieldConfigs.value = {};
  }

  async function handleTestConnection() {
    if (!formValues.data_source_id) {
      showMessage('请先选择数据源', 'warning');
      return;
    }

    try {
      showMessage('正在测试连接...', 'info');
      // TODO: 实际的测试连接 API 调用
      // await testDataSourceConnection(formValues.data_source_id);

      // Mock success
      await new Promise((resolve) => setTimeout(resolve, 1000));
      showMessage('连接测试成功！', 'success');
    } catch (error: any) {
      console.error('测试连接失败:', error);
      showMessage(error?.message || '连接测试失败', 'error');
    }
  }

  // Watch for selectedTables changes
  watch(
    () => selectedTables.value,
    (newVal, oldVal) => {
      const newTables = newVal.filter((t) => !oldVal.includes(t));
      const removedTables = oldVal.filter((t) => !newVal.includes(t));

      // Handle removed tables
      removedTables.forEach((tableName) => {
        const newConfigs = { ...tableFieldConfigs.value };
        delete newConfigs[tableName];
        tableFieldConfigs.value = newConfigs;
        delete loadingFields[tableName];
      });

      // Handle new tables
      newTables.forEach((tableName) => {
        if (!tableFieldConfigs.value[tableName]) {
          fetchTableFields(tableName);
        }
      });

      // Update active tab
      if (newVal.length > 0) {
        if (!newVal.includes(activeTableTab.value)) {
          activeTableTab.value = newVal[0];
        }
      } else {
        activeTableTab.value = '';
      }
    },
    { deep: true },
  );

  // Handle checkbox group change
  function handleCheckboxGroupChange(checkedValues: Array<string | number | boolean>) {
    // Manually trigger field fetching for newly selected tables
    checkedValues.forEach((value) => {
      const tableName = String(value);
      if (!tableFieldConfigs.value[tableName]) {
        fetchTableFields(tableName);
      }
    });

    // Update active tab
    if (checkedValues.length > 0) {
      const firstTable = String(checkedValues[0]);
      if (!checkedValues.map(String).includes(activeTableTab.value)) {
        activeTableTab.value = firstTable;
      }
    }
  }

  async function handleFetchTables() {
    if (!formValues.data_source_id) {
      showMessage(t('tb.dataResource.modal.messages.selectDataSource'), 'warning');
      return;
    }

    try {
      loadingTables.value = true;
      const source = availableSources.value.find((s) => s.data_source_id === formValues.data_source_id);
      if (source?.table) {
        const tables = Array.isArray(source.table) ? source.table : [source.table];
        availableTables.value = tables;
      } else {
        availableTables.value = [];
      }
    } catch (error: any) {
      console.error('获取表列表失败:', error);
      showMessage(error.message || t('tb.dataResource.modal.messages.fetchTablesError'), 'error');
    } finally {
      loadingTables.value = false;
    }
  }

  async function fetchTableFields(tableName: string) {
    if (!formValues.data_source_id) return;

    try {
      loadingFields[tableName] = true;

      // Simulate API delay
      await new Promise((resolve) => setTimeout(resolve, 500));

      // Use mock data for demonstration
      const mockFields = getMockTableFields(tableName);
      const fieldConfigs = mockFields.map((field) => ({
        original_field: field,
        field_mapping: field,
        masking_rule: 'none',
      }));

      tableFieldConfigs.value = {
        ...tableFieldConfigs.value,
        [tableName]: fieldConfigs,
      };
    } catch (error: any) {
      console.error(`获取表 ${tableName} 字段失败:`, error);
      tableFieldConfigs.value = {
        ...tableFieldConfigs.value,
        [tableName]: [
          { original_field: 'id', field_mapping: 'id', masking_rule: 'none' },
          { original_field: 'name', field_mapping: 'name', masking_rule: 'none' },
          { original_field: 'created_at', field_mapping: 'created_at', masking_rule: 'none' },
        ],
      };
    } finally {
      loadingFields[tableName] = false;
    }
  }

  // Mock table fields for testing
  function getMockTableFields(tableName: string): string[] {
    const fieldMap: Record<string, string[]> = {
      users: ['id', 'username', 'email', 'password', 'phone', 'address', 'created_at', 'updated_at', 'status'],
      orders: ['id', 'order_no', 'user_id', 'amount', 'status', 'payment_method', 'created_at', 'updated_at'],
      products: ['id', 'product_name', 'category', 'price', 'stock', 'description', 'created_at', 'updated_at'],
      customers: ['id', 'customer_name', 'email', 'phone', 'address', 'city', 'country', 'created_at'],
      transactions: ['id', 'transaction_id', 'order_id', 'amount', 'currency', 'status', 'payment_time', 'created_at'],
      sales_data: ['id', 'sale_date', 'product_id', 'quantity', 'revenue', 'region', 'salesperson', 'created_at'],
      user_behavior: ['id', 'user_id', 'action_type', 'page_url', 'session_id', 'timestamp', 'device', 'created_at'],
      reports: ['id', 'report_name', 'report_type', 'generated_by', 'generated_at', 'status', 'file_path'],
      metrics: ['id', 'metric_name', 'metric_value', 'metric_type', 'timestamp', 'source', 'created_at'],
    };

    return fieldMap[tableName] || ['id', 'name', 'value', 'created_at', 'updated_at'];
  }

  async function handleSubmit() {
    try {
      const values = await validate();
      setModalProps({ confirmLoading: true });

      if (!deviceId.value) {
        showMessage(t('tb.dataResource.messages.deviceMissing'), 'warning');
        return;
      }

      const payload: CreateDataResourcePayload = {
        resource_name: values.resource_name,
        data_source_name: availableSources.value.find((s) => s.data_source_id === values.data_source_id)?.name || '',
        data_source_id: values.data_source_id,
        type: values.resource_type,
        method: '0',
        level: '0',
        remark: values.description,
      };

      // Include table and field mapping config if database type
      if (values.resource_type === 'database' && selectedTables.value.length > 0) {
        (payload as any).tables = selectedTables.value;
        (payload as any).field_mappings = tableFieldConfigs.value;
      }

      if (isUpdate.value && recordData.value) {
        const updatePayload: UpdateDataResourcePayload = {
          ...payload,
          '.name': recordData.value['.name'],
          '.index': recordData.value['.index'],
          __index: recordData.value.__index || recordData.value['.index'],
          resouce_name: payload.resource_name,
        };
        await updateDataResource(deviceId.value, updatePayload);
        showMessage(t('tb.dataResource.messages.updateSuccess'), 'success');
      } else {
        await createDataResource(deviceId.value, payload);
        showMessage(t('tb.dataResource.messages.createSuccess'), 'success');
      }

      emit('success', payload);
      closeModal();
    } catch (error: any) {
      console.error('提交数据资源失败:', error);
      showMessage(error?.message || t('tb.dataResource.messages.submitError'), 'error');
    } finally {
      setModalProps({ confirmLoading: false });
    }
  }

  function handleCancel() {
    closeModal();
  }
</script>

<style lang="less" scoped>
  .data-resource-modal {
    .section {
      margin-bottom: 16px;

      .section-title {
        font-size: 16px;
        font-weight: 600;
        margin-bottom: 16px;
        padding-bottom: 8px;
        border-bottom: 1px solid #f0f0f0;
      }
    }

    .table-selection-area {
      padding: 16px;
      background: #fafafa;
      border-radius: 4px;
    }

    .table-checkbox-group {
      display: flex;
      flex-wrap: wrap;
      gap: 8px 16px;
      width: 100%;
    }

    .table-checkbox-item {
      flex: 0 0 calc(33.333% - 12px);
      margin-right: 0 !important;
    }
  }
</style>
